import 'dart:typed_data';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:shimo_app/pages/components/hint.dart';

import '../../utils/utils.dart';
import '../frame/frame.dart';
import '../frame/parse.dart';
import '../serial_port.dart';
import '../struct/error.dart';
import '../struct/log.dart';
import '../struct/message.dart';
import '../struct/request_id.dart';
import '../struct/task_progress.dart';

/// 异步操作结果枚举
enum AsyncResult {
  DONE, // 操作完成
  WAIT, // 需要继续等待
  ERROR, // 操作错误
  INTERRUPT // 操作被中断
}

/// 协议抽象基类 - 定义硬件通信协议的标准接口和处理流程
///
/// 所有具体的通信协议都应该继承这个类，实现相应的抽象方法
abstract class Protocol {
  /// 处理同步回复帧
  /// [reply] 接收到的回复帧
  /// 返回bool表示是否处理成功
  bool handleSyncReply(Frame reply);

  /// 处理异步消息
  /// [message] 接收到的异步消息
  /// 返回AsyncResult表示处理结果
  AsyncResult handleAsyncMessage(MessageBean message);

  /// 判断是否为耗时操作
  /// 返回bool，true表示需要等待异步结果，false表示立即返回
  bool isTimeConsuming();

  /// 设置请求ID
  /// 返回RequestId枚举，标识协议类型
  RequestId setRequestId();

  /// 设置处理超时时间（毫秒）
  /// 返回int，0表示不需要等待异步结果
  int setProcessTimeout();

  /// 异步轮询方法（内部使用）
  /// [serialPort] 串口实例
  /// 返回Future<Frame?> 轮询结果帧
  Future<Frame?> _asyncPoll(MySerialPort serialPort) async {
    return await _syncSend(serialPort, RequestId.REQ_POLL, []);
  }

  /// 同步发送方法（内部使用）
  /// [serialPort] 串口实例
  /// [requestId] 请求ID
  /// [data] 发送数据
  /// 返回Future<Frame?> 回复帧
  Future<Frame?> _syncSend(
      MySerialPort serialPort, RequestId requestId, List<int> data) async {
    // 生成请求帧
    final request = Parse.generateRequest(requestId, data);
    int retryTimes = 1; // 重试次数

    // 重试机制
    while (retryTimes-- > 0) {
      //发送请求
      final reply = await serialPort.sendRequest(request);

      // 检查回复是否为空
      if (reply.isEmpty) {
        print("响应空");
        await 200.milliseconds.delay(); // 延迟后重试
        continue;
      }

      // 解析回复帧并检查状态码
      final frame = Parse.isCodeOK(reply);
      if (frame != null) {
        return frame; // 返回有效的帧
      }

      await 350.milliseconds.delay(); // 延迟后重试
    }

    print("接收数据解析异常:${requestId.name}");
    return null; // 重试失败返回null
  }

  /// 协议执行主方法 - 模板方法模式的核心实现
  /// [serialPort] 串口实例
  /// [data] 发送的数据帧
  /// [bus] 事件总线
  /// 返回Future<bool> 执行是否成功
  Future<bool> run(MySerialPort serialPort, Frame data, EventBus bus) async {
    // 步骤1: 发送同步请求
    var frame = await _syncSend(serialPort, setRequestId(), data.toList());
    if (frame == null) {
      return false; // 发送失败
    }

    // 步骤2: 处理同步回复
    if (!handleSyncReply(frame)) {
      print("同步指令响应解析失败");
      return false; // 同步回复处理失败
    }

    // 步骤3: 检查是否为即时操作（不需要等待异步结果）
    if (setProcessTimeout() == 0) {
      return true; // 即时操作直接返回成功
    }

    // 步骤4: 异步操作处理流程
    final start = Utils.getCurrentTimeStamp(); // 记录开始时间
    bool result = false; // 最终结果
    int tryTimes = 3; // 重试次数

    // 超时循环检测
    while (Utils.getCurrentTimeStamp() - start <= setProcessTimeout()) {
      await 300.milliseconds.delay(); // 轮询间隔

      // 发送异步轮询请求
      frame = await _asyncPoll(serialPort);
      if (frame == null) {
        if (--tryTimes <= 0) {
          return false; // 重试次数用尽
        }
        continue; // 继续下一次尝试
      }

      bool getOut = false; // 退出循环标志

      // 解析帧中的多个消息
      while (true) {
        final message = Parse.parseMessage(frame);

        // 检查消息类型并分发处理
        if (message.messageId == MessageId.MSG_NONE) {
          break; // 没有更多消息
        }

        // 电路板状态消息
        if (message.messageId == MessageId.MSG_BOARD_STATUS) {
          final state = message.message.popByte();
          print("-----state:$state-----");
          //todo:eventbus - 需要发送电路板状态事件
          continue; // 继续处理下一条消息
        }

        // 错误设置消息
        if (message.messageId == MessageId.MSG_SET_ERROR) {
          final component = message.message.popByte(); // 组件ID
          final fatal = message.message.popByte() == 1; // 是否致命错误
          final l = message.message.popShort(); // 错误信息长度
          final content = message.message.popString(l); // 错误内容
          print("获取到报错:${component}-$fatal-$content");
          bus.fire(SetComponentError(component, fatal, content)); // 发送错误事件
          continue;
        }

        // 错误清除消息
        if (message.messageId == MessageId.MSG_CLR_ERROR) {
          final l = message.message.popShort(); // 错误信息长度
          final content = message.message.popString(l); // 错误内容
          bus.fire(ClearComponentError(content)); // 发送清除错误事件
          continue;
        }

        // 进度报告消息
        if (message.messageId == MessageId.MSG_REPORT_PROGRESS) {
          final progress = TaskProgress(
              message.message.popByte(), // 容器ID
              message.message.popByte(), // 任务ID
              message.message.popByte(), // 位置
              TaskState.values[message.message.popByte()] // 任务状态
              );
          print(
              "${progress.containerId}-${progress.taskId}-${progress.pos}-${progress.state}");
          bus.fire(progress); // 发送进度事件
          continue;
        }
        // 日志消息
        else if (message.messageId == MessageId.MSG_LOG) {
          final id = message.message.popByte(); // 日志ID
          final l = message.message.popShort(); // 日志长度
          final content = message.message.popString(l); // 日志内容
          bus.fire(DebugLog(id, content)); // 发送日志事件
        }

        // 将消息传递给具体协议处理
        final asyncResult = handleAsyncMessage(message);

        // 根据处理结果决定下一步操作
        if (asyncResult == AsyncResult.DONE) {
          result = true; // 操作完成
          getOut = true; // 退出循环
        } else if (asyncResult == AsyncResult.WAIT) {
          continue; // 继续等待
        } else {
          result = false; // 操作失败
          getOut = true; // 退出循环
        }
      }

      if (getOut) break; // 退出外层循环
    }

    return result; // 返回最终结果
  }
}
